//
//  RSQRCodeScanViewController.m
//  ClientTax
//
//  Created by 侯伟 on 2020/6/29.
//  Copyright © 2020 侯伟. All rights reserved.
//

#import "RSQRCodeScanViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
#define boxW PX(280)

@interface RSQRCodeScanViewController ()<AVCaptureMetadataOutputObjectsDelegate>

@property (strong,nonatomic)AVCaptureDevice* device;

@property (strong,nonatomic)AVCaptureDeviceInput* input;

@property (strong,nonatomic)AVCaptureMetadataOutput* output;

@property (strong,nonatomic)AVCaptureSession* session;

@property (strong,nonatomic)AVCaptureVideoPreviewLayer* preview;

@property (strong,nonatomic)CAGradientLayer *gradientLayer;

@property (nonatomic , strong) UIView* hudView;

@property (nonatomic , strong) UILabel* titleLb;

@end

@implementation RSQRCodeScanViewController

/// 权限检查
/// @param block 回调信息
+ (void)checkState:(BoolBlock)block{
    
    if(![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
        if(block){
            block(NO);
        }
        return;
    }

    AVAuthorizationStatus authorizationStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    
    switch (authorizationStatus) {
        case AVAuthorizationStatusRestricted:
        case AVAuthorizationStatusDenied:{
            [Alert confirm:@"获取相机权限" message:@"您还没有启动相机的使用权限，是否现在启用?" completion:^(BOOL Bool) {
                if(Bool){
                    [Founction openURLString:UIApplicationOpenSettingsURLString];
                }else{
                    [self closeViewControllerAnimated:YES];
                }
            }];
        }
            break;
        case AVAuthorizationStatusAuthorized:{
            if(block){
                block(YES);
            }
        }
            break;
        case AVAuthorizationStatusNotDetermined:{
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
                [Queue asyncMain:^{
                    if (block) {
                         block(granted);
                    }
                }];
            }];
        }
            break;
        default:
            break;
    }
}

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    if(_session){
        [self start];
    }
}

- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    if(_session){
        [self stop];
    }
}


- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.edgesForExtendedLayout = UIRectEdgeNone;
    
    self.title = @"扫一扫";
    
    [self.view addSubview:self.hudView];
    
    CGFloat x = (CGRectGetWidth(self.hudView.frame) - boxW)*0.5;
    CGFloat y = (CGRectGetHeight(self.hudView.frame) - boxW)*0.5 - 60;
    CGFloat height = boxW;
    
    self.titleLb.frame = CGRectMake(x, y+height+26, boxW, PX(17));
    [self.view addSubview:self.titleLb];
    
    
    //检查相机权限
    [self checkState:^(BOOL available) {
        if(available){
            [self setupSession];
        }else{
            [Toast toast:@"相机不可用"];
            [self closeViewControllerAnimated:YES];
        }
    }];
}


/// 权限检查
/// @param block 回调信息
- (void)checkState:(void(^)(BOOL available))block{
    
    if(![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
        if(block){
            block(NO);
        }
        return;
    }

    AVAuthorizationStatus authorizationStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    
    switch (authorizationStatus) {
        case AVAuthorizationStatusRestricted:
        case AVAuthorizationStatusDenied:{
            [Alert confirm:@"获取相机权限" message:@"您还没有启动相机的使用权限，是否现在启用?" completion:^(BOOL Bool) {
                if(Bool){
                    [Founction openURLString:UIApplicationOpenSettingsURLString];
                }else{
                    [self closeViewControllerAnimated:YES];
                }
            }];
        }
            break;
        case AVAuthorizationStatusAuthorized:{
            if(block){
                block(YES);
            }
        }
            break;
        case AVAuthorizationStatusNotDetermined:{
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
                [Queue asyncMain:^{
                    if (block) {
                         block(granted);
                    }
                }];
            }];
        }
            break;
        default:
            break;
    }
}

/// init
- (void)setupSession{
    
    // Device
    _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
    // Input
    _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
    
    // Output
    _output = [[AVCaptureMetadataOutput alloc] init];
    [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    [_output setRectOfInterest:CGRectMake(((CGRectGetHeight(self.hudView.frame) - boxW)*0.5 - 60)/SCREEN_HEIGHT,
    (CGRectGetWidth(self.view.frame) - boxW)*0.5/SCREEN_WIDTH,
    boxW/SCREEN_HEIGHT,
    boxW/SCREEN_WIDTH)];
    
    
    // Session
    _session = [[AVCaptureSession alloc]init];
    [_session setSessionPreset:AVCaptureSessionPresetHigh];
    

    if([_session canAddInput:self.input]){
        [_session addInput:self.input];
    }
    if([_session canAddOutput:self.output]){
        [_session addOutput:self.output];
    }
    

    _output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode];
    
    // Preview
    _preview =[AVCaptureVideoPreviewLayer layerWithSession:_session];
    _preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
    _preview.frame = self.view.layer.bounds;
    [self.view.layer insertSublayer:_preview atIndex:0];
    
    [self start];
}


/// 开始扫码
- (void)start{
    [_session startRunning];
    [self.hudView.layer addSublayer:self.gradientLayer];
    [self.gradientLayer addAnimation:[self positionBasicAnimate] forKey:@"position"];
}

/// 结束扫码
- (void)stop{
    [_session stopRunning];
    
    [self.gradientLayer removeAnimationForKey:@"position"];
    [self.gradientLayer removeFromSuperlayer];
}

#pragma mark AVCaptureMetadataOutputObjectsDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
    NSString *stringValue;
    if([metadataObjects count] > 0){
        [self playSound];
        //停止扫描
        [self stop];

        AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
        stringValue = metadataObject.stringValue;
        
        if(self.scanBlock){
            [self closeViewControllerAnimated:NO];
            self.scanBlock(stringValue);
        }
    }
}

- (void)playSound{
    NSURL *url = [[NSBundle mainBundle] URLForResource:@"scanSuccess.wav" withExtension:nil];
    SystemSoundID soundID = 1016;
    OSStatus status = AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &soundID);
    if(0 == status){
        AudioServicesPlaySystemSound(soundID);
    }
}
/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

#pragma mark  -- box

#pragma mark - lazy
//懵层
- (UIView *)hudView
{
    if (!_hudView) {
        UIView* hudView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT-IPHONE_NAVIGATION_BAR_HEIGHT)];
        CGFloat x = (CGRectGetWidth(hudView.frame) - boxW)*0.5;
        CGFloat y = (CGRectGetHeight(hudView.frame) - boxW)*0.5 - 60;
        CGFloat height = boxW;
        
        //镂空
        CGRect qrRect = CGRectMake(x,y,height, height);
        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:hudView.frame cornerRadius:0];
        UIBezierPath *circlePath = [UIBezierPath bezierPathWithRect:qrRect];
        [path appendPath:circlePath];
        [path setUsesEvenOddFillRule:YES];
        CAShapeLayer *fillLayer = [CAShapeLayer layer];
        fillLayer.path = path.CGPath;
        fillLayer.fillRule = kCAFillRuleEvenOdd;
        fillLayer.fillColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0.4].CGColor;
        fillLayer.opacity = 0.5;
        [hudView.layer addSublayer:fillLayer];
        
        //白色矩形
        UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRect:CGRectMake(x, y, height, height)];
        CAShapeLayer *shapLayer = [CAShapeLayer layer];
        shapLayer.backgroundColor = UIColor.clearColor.CGColor;
        shapLayer.path = bezierPath.CGPath;
        shapLayer.lineWidth = 1.0;
        shapLayer.strokeColor = RGBACOLOR(0xFF, 0xFF, 0xFF, 0.3).CGColor;
        shapLayer.fillColor = RGBACOLOR(0xFF, 0xFF, 0xFF, 0.1).CGColor;
        [hudView.layer addSublayer:shapLayer];
        
        //四个角落
        UIBezierPath *cornerBezierPath = [UIBezierPath bezierPath];
        
        [cornerBezierPath moveToPoint:CGPointMake(x-(2-Size_1PX), y+32)];//左上角
        [cornerBezierPath addLineToPoint:CGPointMake(x-(2-Size_1PX), y-(2-Size_1PX))];
        [cornerBezierPath addLineToPoint:CGPointMake(x+32, y-(2-Size_1PX))];
        
        [cornerBezierPath moveToPoint:CGPointMake(x+height-32+(2-Size_1PX), y-(2-Size_1PX))];//右上角
        [cornerBezierPath addLineToPoint:CGPointMake(x+height+(2-Size_1PX), y-(2-Size_1PX))];
        [cornerBezierPath addLineToPoint:CGPointMake(x+height+(2-Size_1PX), y+32-(2-Size_1PX))];
        
        [cornerBezierPath moveToPoint:CGPointMake(x+height+(2-Size_1PX), y+height-32+(2-Size_1PX))];//右下角
        [cornerBezierPath addLineToPoint:CGPointMake(x+height+(2-Size_1PX), y+height+(2-Size_1PX))];
        [cornerBezierPath addLineToPoint:CGPointMake(x+height-32+(2-Size_1PX), y+height+(2-Size_1PX))];
        
        [cornerBezierPath moveToPoint:CGPointMake(x+32+(2-Size_1PX), y+height+(2-Size_1PX))];//左下角
        [cornerBezierPath addLineToPoint:CGPointMake(x-(2-Size_1PX), y+height+(2-Size_1PX))];
        [cornerBezierPath addLineToPoint:CGPointMake(x-(2-Size_1PX), y+height-32+(2-Size_1PX))];
        
        CAShapeLayer *cornerShapLayer = [CAShapeLayer layer];
        cornerShapLayer.backgroundColor = UIColor.clearColor.CGColor;
        cornerShapLayer.path = cornerBezierPath.CGPath;
        cornerShapLayer.lineWidth = 3.0;
        cornerShapLayer.strokeColor = COLOR_THEME.CGColor;
        cornerShapLayer.fillColor = UIColor.clearColor.CGColor;
        [hudView.layer addSublayer:cornerShapLayer];
        _hudView = hudView;
    }
    return _hudView;
}

//光标
- (CAGradientLayer*)gradientLayer{
    if(!_gradientLayer){
        
        CGFloat x = (CGRectGetWidth(self.hudView.frame) - boxW)*0.5;
        CGFloat y = (CGRectGetHeight(self.hudView.frame) - boxW)*0.5 - 60;
        CGFloat height = boxW;
        
        CAGradientLayer *gradientLayer = [CAGradientLayer layer];
        gradientLayer.frame = CGRectMake(x+3, y+3, height-6, 4.0);
        gradientLayer.colors = @[(__bridge id)[UIColor colorWithRed:0x5A/255.0 green:0x8D/255.0 blue:0xEE/255.0 alpha:0.1].CGColor, (__bridge id)[UIColor colorWithRed:0x5A/255.0 green:0x8D/255.0 blue:0xEE/255.0 alpha:1.0].CGColor, (__bridge id)[UIColor colorWithRed:0x5A/255.0 green:0x8D/255.0 blue:0xEE/255.0 alpha:1.0].CGColor, (__bridge id)[UIColor colorWithRed:0x5A/255.0 green:0x8D/255.0 blue:0xEE/255.0 alpha:1.0].CGColor, (__bridge id)[UIColor colorWithRed:0x5A/255.0 green:0x8D/255.0 blue:0xEE/255.0 alpha:0.1].CGColor];//[self colorWithBasicColor:COLOR_THEME];
        gradientLayer.startPoint = CGPointMake(0.97, 0);
        gradientLayer.endPoint = CGPointMake(0.06, 0);
        gradientLayer.locations = @[@(0), @(0.3f), @(0.5f), @(0.8f), @(1.0f)];
        _gradientLayer = gradientLayer;
    }
    return _gradientLayer;
}

- (UILabel*)titleLb{
    if(!_titleLb){
        _titleLb = [UILabel lableWithFont:FONT_FIT(14) color:UIColor.whiteColor text:@"将二维码放入框内，即可扫码登录"];
        _titleLb.alpha = 0.8;
        _titleLb.textAlignment = NSTextAlignmentCenter;
    }
    return _titleLb;
}

//动画
- (CABasicAnimation *)positionBasicAnimate
{
    CGFloat x = (CGRectGetWidth(self.view.frame) - boxW)*0.5;
    CGFloat y = (CGRectGetHeight(self.hudView.frame) - boxW)*0.5 - 60;
    CGFloat height = boxW;
    CABasicAnimation *animate = [CABasicAnimation animationWithKeyPath:@"position"];
    animate.removedOnCompletion = NO;
    animate.duration = 2.0;
    animate.fillMode = kCAFillModeRemoved;
    animate.repeatCount = HUGE_VAL;
    animate.fromValue = [NSValue valueWithCGPoint:CGPointMake(x+height*0.5, y+3)];
    animate.toValue = [NSValue valueWithCGPoint:CGPointMake(x+height*0.5, y+height-3)];
    animate.autoreverses = YES;
    return animate;
}

- (NSArray<UIColor *> *)colorWithBasicColor:(UIColor *)basicCoclor
{
    CGFloat R, G, B, amplitude;
    amplitude = 90/255.0;
    NSInteger numComponents = CGColorGetNumberOfComponents(basicCoclor.CGColor);
    NSArray *colors;
    if (numComponents == 4)
    {
        const CGFloat *components = CGColorGetComponents(basicCoclor.CGColor);
        R = components[0];
        G = components[1];
        B = components[2];
        colors = @[(id)[UIColor colorWithWhite:0.667 alpha:0.2].CGColor,
                   (id)basicCoclor.CGColor,
                   (id)[UIColor colorWithRed:R+amplitude > 1.0 ? 1.0:R+amplitude
                                        green:G+amplitude > 1.0 ? 1.0:G+amplitude
                                        blue:B+amplitude > 1.0 ? 1.0:B+amplitude alpha:1.0].CGColor,
                   (id)[UIColor colorWithRed:R+amplitude > 1.0 ? 1.0:R+amplitude*2
                                        green:G+amplitude > 1.0 ? 1.0:G+amplitude*2
                                        blue:B+amplitude > 1.0 ? 1.0:B+amplitude*2 alpha:1.0].CGColor,
                   (id)[UIColor colorWithRed:R+amplitude > 1.0 ? 1.0:R+amplitude
                                        green:G+amplitude > 1.0 ? 1.0:G+amplitude
                                        blue:B+amplitude > 1.0 ? 1.0:B+amplitude alpha:1.0].CGColor,
                   (id)basicCoclor.CGColor,
                   (id)[UIColor colorWithWhite:0.667 alpha:0.2].CGColor,];
    }else{
        colors = @[(id)basicCoclor.CGColor,
                   (id)basicCoclor.CGColor,];
    }
    return colors;
}


@end
